home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1993 July / InfoMagic USENET CD-ROM July 1993.ISO / sources / unix / volume14 / jove4.9 / part05 < prev    next >
Encoding:
Internet Message Format  |  1988-04-25  |  48.5 KB

  1. Subject:  v14i061:  Jove, an emacs variant, version 4.9, Part05/21
  2. Newsgroups: comp.sources.unix
  3. Sender: sources
  4. Approved: rsalz@uunet.UU.NET
  5.  
  6. Submitted-by: Jonathan Payne <jpayne@cs.rochester.edu>
  7. Posting-number: Volume 14, Issue 61
  8. Archive-name: jove4.9/part05
  9.  
  10. #! /bin/sh
  11. # This is a shell archive.  Remove anything before this line, then unpack
  12. # it by saving it into a file and typing "sh file".  To overwrite existing
  13. # files, type "sh file -c".  You can also feed this as standard input via
  14. # unshar, or by typing "sh <file", e.g..  If this archive is complete, you
  15. # will see the following message at the end:
  16. #        "End of archive 5 (of 21)."
  17. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  18. if test -f './Readme.dos' -a "${1}" != "-c" ; then 
  19.   echo shar: Will not clobber existing file \"'./Readme.dos'\"
  20. else
  21. echo shar: Extracting \"'./Readme.dos'\" \(11028 characters\)
  22. sed "s/^X//" >'./Readme.dos' <<'END_OF_FILE'
  23. X###########################################################################
  24. X# This program is Copyright (C) 1986, 1987, 1988 by Jonathan Payne.  JOVE #
  25. X# is provided to you without charge, and with no warranty.  You may give  #
  26. X# away copies of JOVE, including sources, provided that this notice is    #
  27. X# included in all the files.                                              #
  28. X###########################################################################
  29. X
  30. HOW TO GET STARTED WITH JOVE:
  31. X=============================
  32. X
  33. You can immediately start using Jove if you have an IBMPC
  34. compatible PC, XT or AT. You can fine tune some things by setting
  35. certain environment variables, but it's not really necessary
  36. If your computer is not IBM BIOS compatible, you have to set some 
  37. environment variables before starting Jove.
  38. What follows is a description of those variables.
  39. X
  40. ENVIRONMENT VARIABLES USED BY JOVE:
  41. X===================================
  42. X
  43. TMP (or TMPDIR)
  44. Jove uses the value of TMP to determine the directory where it should
  45. put its temporary file. The default is the current directory, and this
  46. is probably not what you want. In general editing is faster, if TMP
  47. points to a ramdisk, like "set tmp=d:". You have to know however that
  48. the temporary file can grow quite big when editing many big files at
  49. once. So please make sure that you have enough space available on your
  50. ramdisk. If Jove runs out of space on the device which holds the
  51. temporary file, you have to leave the editor immediately. You can save
  52. your work without any trouble, but you have to start over. Please note
  53. also that the current version of Jove has a big cache for the
  54. temporary file in memory, which makes it quite fast even if you don't
  55. have a ramdisk.
  56. X
  57. DESCRIBE
  58. This variable tells Jove, where it can find the file that holds the
  59. online documentation. You should set DESCRIBE to the complete
  60. path-specification of the file "cmds.doc", which is included as part
  61. of the documentation. The default for DESCRIBE is "c:/unix/cmds.doc".
  62. X
  63. JOVERC
  64. This is the complete path for Jove's startup file. All commands in the
  65. file, that JOVERC points to, are executed every time when you run
  66. Jove. If there is a file called "jove.rc" in the current directory,
  67. then it is also "sourced", ie. the commands in that file are executed.
  68. That way you can customize Jove to your own taste.
  69. X
  70. The next two variables are not used by the IBMPC version, and have to
  71. do with specifying the type of terminal in use on a generic msdos
  72. computer.
  73. X
  74. TERM
  75. This variable should specify the name of the terminal you are using.
  76. For example, if you have a DEC vt-100 terminal attached to your msdos
  77. computer, you should give the command "set TERM=vt100" prior to
  78. starting Jove.
  79. X
  80. TERMCAP
  81. This environment variable holds the name of a database with
  82. descriptions of different terminal types. If you are familiar with the
  83. Unix operating system, you probably know about TERMCAP. For each
  84. terminal type, specified by TERM, the TERMCAP database holds an entry,
  85. which describes how to set the cursor, how to scroll, and many other
  86. things, for that particular terminal. A small example TERMCAP file
  87. comes with Jove. If your terminal is not included there, you should ask a
  88. local Unix guru for help. If you don't have one, you can ask me.
  89. X
  90. METAKEY
  91. Some kinds of terminals have a special shift key that Jove can recognize, 
  92. the so called MetaKey. When the environment variable METAKEY is set, Jove
  93. assumes that you have such a terminal, and treats the codes that your
  94. terminal sends in a slightly different way. Pressing down the MetaKey
  95. and another key at the same time is a then a shorthand for pressing
  96. first the "esc" key, and then the other key.
  97. X
  98. X
  99. DIFFERENT VERSIONS OF JOVE:
  100. X===========================
  101. X
  102. The text above already indicated that Jove comes in different versions
  103. for different types of computers. Not only that, there also exist
  104. versions that differ in the way they use the memory of the computer. 
  105. X
  106. The "large" versions of Jove use all the memory available if it is
  107. necessary. The temporary file can grow infinitely large in those
  108. versions. The number of lines that can be edited with the large
  109. version is about 20000 to 25000 on a PC with 640 kB of memory. Note
  110. that there is no limit on the size of the file itself.
  111. The "medium" versions of Jove are more conservative in their use of
  112. memory. They always take up about 130 kB of memory, which leaves a big
  113. rest for executing large programs, like the C-Compiler from within
  114. Jove. The size of the temporary file is also limited to 512 kB in the
  115. medium versions. The leads to a limit of approximately 4500 to 5000
  116. lines that can be edited at one time. 
  117. The standard executable files that are distributed in binary form, are
  118. usually the large ones. If you need a medium version, you either have
  119. to recompile Jove from the sources (see below), or you can get get
  120. it from someone else who has compiled it, for example from me.
  121. X
  122. There currently exist versions of Jove for three different types of
  123. msdos computers. PCJOVE is for IBMPC compatible computers. Compatible
  124. means here that the ROM Bios of your computer has to support the same
  125. Video output calls as the PC's. So even if your "clone" has trouble
  126. with many other programs, there's a high chance that Jove will work.
  127. MSJOVE should generally run on any computer that runs the msdos
  128. operating system. It strictly uses only well documented system calls
  129. to do its task. RBJOVE is a special version of MSJOVE for DEC Rainbow
  130. computers, which uses the Rainbows Bios for screen output and keyboard
  131. input. This makes it much faster than MSJOVE on the Rainbow.
  132. X
  133. X
  134. DIFFERENCES BETWEEN JOVE UNDER MSDOS AND UNIX JOVE:
  135. X===================================================
  136. X
  137. The msdos version of Jove currently supports all of the features that
  138. are possible to implement under msdos in a reasonable way.
  139. Version 4.8b in particular supports:
  140. X    filename completion
  141. X    comment filling 
  142. X    creation of backup files
  143. X    word abbreviation mode
  144. X    Lisp mode
  145. X    change directory within Jove
  146. X    executing commands from within Jove
  147. X    filtering regions through msdos commands
  148. You have to look into the manual for more explanations of these
  149. features. The things that are missing under msdos are:
  150. X    spell-buffer (obsolete under msdos)
  151. X    interactive shells in a window (not possible)
  152. There are however some features added, which are specific to the PC
  153. version.
  154. X
  155. Variables:
  156. X Background-color specifies the background color of the screen. The default
  157. X    value is 0, which stands for black.
  158. X Foreground-color specifies the foreground color of the screen. The default
  159. X    is 1, which stands for white. The attribute used for writing to the
  160. X    screen is formed by (bg&7)<<4 & (fg&7).
  161. X Mode-line-color specifies the color of the modeline. Its default
  162. X    value is 0, and in that case it is drawn in reverse video. If it has
  163. X    any other value, this value is used as the attribute in Bios calls. 
  164. X (note that on a monochrome monitor the best thing is to leave the
  165. X default colors - anything else can lead to blank screens very easily)
  166. X
  167. Commands:
  168. X Scroll-previous-page continuously scrolls down screen-full lines.
  169. X Scroll-next-page continuously scrolls up screen-full lines.
  170. X Select-buffer-n, where n is in the range 0 to 9, selects buffer n as the
  171. X    working buffer. These commands are bound to the <alt>[0-9] keys by
  172. X    default. For example, pressing the alt key and 3 at the same time
  173. X    switches immediately to buffer 3.
  174. X
  175. General:
  176. X PCJOVE supports the whole 8 bit character set of the IBMPC. You can
  177. X use all the line drawing characters in your files. It also knows
  178. X about some special foreign characters (Umlaute), which are treated
  179. X correctly as part of words and in case conversions.
  180. X
  181. X
  182. VIDEO MODES ON THE IBMPC:
  183. X=========================
  184. X
  185. This concerns PCJOVE only. When Jove is started, it automatically
  186. checks which video mode is currently used, and adjusts itself
  187. correspondingly. This means that Jove will work correctly even in
  188. X40x25 mode. If you have an Ega card, and want to use the special mode
  189. with 43 lines, set the environment variable TERM to the value EGA, or
  190. set the variable EGA to any value. This will tell Jove to set the
  191. screen in 80x43 mode. The regular 80x25 mode is restored upon exit.
  192. On a color monitor, you can change the screen colors by using the
  193. commands mentioned above.
  194. There is a problem in using Jove together with Hershey
  195. MicroComputing's FansiConsole screen driver. FansiConsole doesn't
  196. properly set some of the values in the Bios control area. This usually
  197. leads to a crash when Jove starts. You can restore the information
  198. Jove needs by giving the command "mode co80" before starting Jove.
  199. Note that Kermit version 2.30 has the same problem, and that it can
  200. only be fixed by fixing FansiConsole.
  201. X
  202. X
  203. COMPILING JOVE UNDER MSDOS:
  204. X===========================
  205. X
  206. Jove can currently only be compiled with the Version 5.0 of the
  207. Microsoft C Compiler. Jove uses some library function calls that were
  208. not included with version 4.0 or earlier of Microsoft C. The makefile
  209. that is included with the sources will not work with Microsofts lousy
  210. make. I recommend that you use ndmake, a public domain (or is it
  211. shareware) make utility, which is much better than Microsofts.
  212. Jove can be compiled with the medium, or the large memory model. To
  213. get the IBMPC version, the option "-DIBMPC" should be given at the
  214. command line for the Compiler. Similarly, the define for the Rainbow
  215. version is RAINBOW. The variable MSDOS is always defined by the
  216. compiler. If you want to disable some features you can do so by making
  217. changes to tune.h.
  218. If you want to give away the version of Jove you are compiling to
  219. other people, don't use the loop optimizations or intrinsic
  220. functions!!! The compiler currently has some bugs in the optimizer,
  221. which causes it to produce wrong code sometimes, and in unpredictable
  222. places. Look at the function DoJustify(), in paragraph.c, for an
  223. example. Note that the #pragma is commented out. because compilers on
  224. other machines don't like it. If you find that the version you just
  225. compiled behaves strange in some way, and you compiled with
  226. optimizations on, check whether it works ok with optimizations
  227. disabled before you tell all the world about a new bug in Jove.
  228. If you want to compile MSJOVE or RBJOVE, you need the library MTERMLIB
  229. or LTERMLIB, for medium or large memory model, respectively. These
  230. libraries contain the functions for dealing with the termcap database.
  231. X
  232. If you want to compile Jove with Turbo-C, the port has already been
  233. done by Brian Campbell (brianc@cognos.uucp). A separate file with the
  234. diffs is currently available from him, and will probably be included
  235. as ifdefs in future versions.
  236. X
  237. If you find a bug in Jove, have some questions, or some suggestions,
  238. you are always welcome. Just send mail to me. My address is:
  239. X
  240. X          Karl Gegenfurtner
  241. X
  242. arpa:     karl@hipl.psych.nyu.edu
  243. uucp      {ihnp4|seismo|allegra}!cmcl2!xp!hipl!karl
  244. usps:     New York University
  245. X          Dept. of Psychology
  246. X          6 Washington Place 8th floor
  247. X          New York, NY 10003
  248. END_OF_FILE
  249. if test 11028 -ne `wc -c <'./Readme.dos'`; then
  250.     echo shar: \"'./Readme.dos'\" unpacked with wrong size!
  251. fi
  252. # end of './Readme.dos'
  253. fi
  254. if test -f './ctype.c' -a "${1}" != "-c" ; then 
  255.   echo shar: Will not clobber existing file \"'./ctype.c'\"
  256. else
  257. echo shar: Extracting \"'./ctype.c'\" \(11238 characters\)
  258. sed "s/^X//" >'./ctype.c' <<'END_OF_FILE'
  259. X/***************************************************************************
  260. X * This program is Copyright (C) 1986, 1987, 1988 by Jonathan Payne.  JOVE *
  261. X * is provided to you without charge, and with no warranty.  You may give  *
  262. X * away copies of JOVE, including sources, provided that this notice is    *
  263. X * included in all the files.                                              *
  264. X ***************************************************************************/
  265. X
  266. X#include "jove.h"
  267. X#include "ctype.h"
  268. X
  269. int    SyntaxTable = FUNDAMENTAL;    /* Current table to use. */
  270. X
  271. X#ifdef ASCII
  272. char CharTable[NMAJORS][128] = {
  273. X#else /* IBMPC or MAC */
  274. char CharTable[NMAJORS][256] = {
  275. X#endif /* ASCII */
  276. X{    _C,    _C,    _C,    _C,    _C,    _C,    _C,    _C,
  277. X    _C,    _C,    _C,    _C,    _C,    _C,    _C,    _C,
  278. X    _C,    _C,    _C,    _C,    _C,    _C,    _C,    _C,
  279. X    _C,    _C,    _C,    _C,    _C,    _C,    _C,    _C,
  280. X    _P,    _P,    _P,    _P,    _P,    _P,    _P,    _P,
  281. X    _Op|_P,    _Cl|_P,    _P,    _P,    _P,    _P,    _P,    _P,
  282. X    _W|_N,    _W|_N,    _W|_N,    _W|_N,    _W|_N,    _W|_N,    _W|_N,    _W|_N,
  283. X    _W|_N,    _W|_N,    _P,    _P,    _P,    _P,    _P,    _P,
  284. X    _P,    _W|_U,    _W|_U,    _W|_U,    _W|_U,    _W|_U,    _W|_U,    _W|_U,
  285. X    _W|_U,    _W|_U,    _W|_U,    _W|_U,    _W|_U,    _W|_U,    _W|_U,    _W|_U,
  286. X    _W|_U,    _W|_U,    _W|_U,    _W|_U,    _W|_U,    _W|_U,    _W|_U,    _W|_U,
  287. X    _W|_U,    _W|_U,    _W|_U,    _Op|_P,    _P,    _Cl|_P,    _P,    _P,
  288. X    _P,    _W|_L,    _W|_L,    _W|_L,    _W|_L,    _W|_L,    _W|_L,    _W|_L,
  289. X    _W|_L,    _W|_L,    _W|_L,    _W|_L,    _W|_L,    _W|_L,    _W|_L,    _W|_L,
  290. X    _W|_L,    _W|_L,    _W|_L,    _W|_L,    _W|_L,    _W|_L,    _W|_L,    _W|_L,
  291. X#ifdef ASCII
  292. X    _W|_L,    _W|_L,    _W|_L,    _Op|_P,    _P,    _Cl|_P,    _P,    _C    },
  293. X#endif
  294. X#ifdef IBMPC
  295. X    _W|_L,    _W|_L,    _W|_L,    _Op|_P,    _P,    _Cl|_P,    _P,    _C,
  296. X    0, _W|_L, 0, 0, _W|_L, 0, 0, 0, 0, 0, 0, 0, 0, 0, _W|_U, 0,
  297. X    0, 0, 0, 0, _W|_L, 0, 0, 0, 0, _W|_U, _W|_U, 0, 0, 0, 0, 0,
  298. X    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  299. X    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  300. X    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  301. X    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  302. X    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  303. X    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
  304. X    },
  305. X
  306. X#endif /* IBMPC */
  307. X#ifdef MAC    /* See Inside Macintosh Vol One p. 247 */
  308. X    _W|_L,    _W|_L,    _W|_L,    _Op|_P,    _P,    _Cl|_P,    _P,    _C,
  309. X    _W|_U, _W|_U, _W|_U, _W|_U, _W|_U, _W|_U, _W|_U, _W|_L, 
  310. X    _W|_L, _W|_L, _W|_L, _W|_L, _W|_L, _W|_L, _W|_L, _W|_L, 
  311. X    _W|_L, _W|_L, _W|_L, _W|_L, _W|_L, _W|_L, _W|_L, _W|_L, 
  312. X    _W|_L, _W|_L, _W|_L, _W|_L, _W|_L, _W|_L, _W|_L, _W|_L, 
  313. X    _P, _P, _P, _P, _P, _P, _P, _P, 
  314. X    _P, _P, _P, _P, _P, _P, _W|_U, _W|_U,
  315. X    _P, _P, _P, _P, _P, _W|_U, _W|_L, _W|_U, 
  316. X    _W|_U, _W|_L, _P, _P, _P, _W|_U, _W|_L, _W|_L,
  317. X    _P, _P, _P, _P, _P, _P, _W|_U, _P,
  318. X    _P, _P, _P, _W|_U, _W|_U, _W|_U, _W|_U, _W|_U, 
  319. X    _P, _P, _P, _P, _P, _P, _P, _P, 
  320. X    _W|_U, 0, 0, 0, 0, 0, 0, 0, 
  321. X    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  322. X    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
  323. X    },
  324. X#endif /* MAC */
  325. X
  326. X{    _C,    _C,    _C,    _C,    _C,    _C,    _C,    _C,
  327. X    _C,    _C,    _C,    _C,    _C,    _C,    _C,    _C,
  328. X    _C,    _C,    _C,    _C,    _C,    _C,    _C,    _C,
  329. X    _C,    _C,    _C,    _C,    _C,    _C,    _C,    _C,
  330. X    _P,    _P,    _P,    _P,    _P,    _P,    _P,    _P|_W,
  331. X    _Op|_P,    _Cl|_P,    _P,    _P,    _P,    _P,    _P,    _P,
  332. X    _W|_N,    _W|_N,    _W|_N,    _W|_N,    _W|_N,    _W|_N,    _W|_N,    _W|_N,
  333. X    _W|_N,    _W|_N,    _P,    _P,    _P,    _P,    _P,    _P,
  334. X    _P,    _W|_U,    _W|_U,    _W|_U,    _W|_U,    _W|_U,    _W|_U,    _W|_U,
  335. X    _W|_U,    _W|_U,    _W|_U,    _W|_U,    _W|_U,    _W|_U,    _W|_U,    _W|_U,
  336. X    _W|_U,    _W|_U,    _W|_U,    _W|_U,    _W|_U,    _W|_U,    _W|_U,    _W|_U,
  337. X    _W|_U,    _W|_U,    _W|_U,    _Op|_P,    _P,    _Cl|_P,    _P,    _P,
  338. X    _P,    _W|_L,    _W|_L,    _W|_L,    _W|_L,    _W|_L,    _W|_L,    _W|_L,
  339. X    _W|_L,    _W|_L,    _W|_L,    _W|_L,    _W|_L,    _W|_L,    _W|_L,    _W|_L,
  340. X    _W|_L,    _W|_L,    _W|_L,    _W|_L,    _W|_L,    _W|_L,    _W|_L,    _W|_L,
  341. X#ifdef ASCII
  342. X    _W|_L,    _W|_L,    _W|_L,    _Op|_P,    _P,    _Cl|_P,    _P,    _C    },
  343. X#endif /* ASCII */
  344. X#ifdef IBMPC
  345. X    _W|_L,    _W|_L,    _W|_L,    _Op|_P,    _P,    _Cl|_P,    _P,    _C,
  346. X    0, _W|_L, 0, 0, _W|_L, 0, 0, 0, 0, 0, 0, 0, 0, 0, _W|_U, 0,
  347. X    0, 0, 0, 0, _W|_L, 0, 0, 0, 0, _W|_U, _W|_U, 0, 0, 0, 0, 0,
  348. X    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  349. X    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  350. X    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  351. X    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  352. X    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  353. X    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
  354. X},
  355. X
  356. X#endif /* IBMPC */
  357. X#ifdef MAC    /* See Inside Macintosh Vol One p. 247 */
  358. X    _W|_L,    _W|_L,    _W|_L,    _Op|_P,    _P,    _Cl|_P,    _P,    _C,
  359. X    _W|_U, _W|_U, _W|_U, _W|_U, _W|_U, _W|_U, _W|_U, _W|_L, 
  360. X    _W|_L, _W|_L, _W|_L, _W|_L, _W|_L, _W|_L, _W|_L, _W|_L, 
  361. X    _W|_L, _W|_L, _W|_L, _W|_L, _W|_L, _W|_L, _W|_L, _W|_L, 
  362. X    _W|_L, _W|_L, _W|_L, _W|_L, _W|_L, _W|_L, _W|_L, _W|_L, 
  363. X    _P, _P, _P, _P, _P, _P, _P, _P, 
  364. X    _P, _P, _P, _P, _P, _P, _W|_U, _W|_U,
  365. X    _P, _P, _P, _P, _P, _W|_U, _W|_L, _W|_U, 
  366. X    _W|_U, _W|_L, _P, _P, _P, _W|_U, _W|_L, _W|_L,
  367. X    _P, _P, _P, _P, _P, _P, _W|_U, _P,
  368. X    _P, _P, _P, _W|_U, _W|_U, _W|_U, _W|_U, _W|_U, 
  369. X    _P, _P, _P, _P, _P, _P, _P, _P, 
  370. X    _W|_U, 0, 0, 0, 0, 0, 0, 0, 
  371. X    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  372. X    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
  373. X    },
  374. X#endif /* MAC */
  375. X
  376. X{    _C,    _C,    _C,    _C,    _C,    _C,    _C,    _C,
  377. X    _C,    _C,    _C,    _C,    _C,    _C,    _C,    _C,
  378. X    _C,    _C,    _C,    _C,    _C,    _C,    _C,    _C,
  379. X    _C,    _C,    _C,    _C,    _C,    _C,    _C,    _C,
  380. X    _P,    _P,    _P,    _P,    _P|_W,    _P,    _P,    _P,
  381. X    _Op|_P,    _Cl|_P,    _P,    _P,    _P,    _P,    _P,    _P,
  382. X    _W|_N,    _W|_N,    _W|_N,    _W|_N,    _W|_N,    _W|_N,    _W|_N,    _W|_N,
  383. X    _W|_N,    _W|_N,    _P,    _P,    _P,    _P,    _P,    _P,
  384. X    _P,    _W|_U,    _W|_U,    _W|_U,    _W|_U,    _W|_U,    _W|_U,    _W|_U,
  385. X    _W|_U,    _W|_U,    _W|_U,    _W|_U,    _W|_U,    _W|_U,    _W|_U,    _W|_U,
  386. X    _W|_U,    _W|_U,    _W|_U,    _W|_U,    _W|_U,    _W|_U,    _W|_U,    _W|_U,
  387. X    _W|_U,    _W|_U,    _W|_U,    _Op|_P,    _P,    _Cl|_P,    _P,    _P|_W,
  388. X    _P,    _W|_L,    _W|_L,    _W|_L,    _W|_L,    _W|_L,    _W|_L,    _W|_L,
  389. X    _W|_L,    _W|_L,    _W|_L,    _W|_L,    _W|_L,    _W|_L,    _W|_L,    _W|_L,
  390. X    _W|_L,    _W|_L,    _W|_L,    _W|_L,    _W|_L,    _W|_L,    _W|_L,    _W|_L,
  391. X#ifdef ASCII
  392. X    _W|_L,    _W|_L,    _W|_L,    _Op|_P,    _P,    _Cl|_P,    _P,    _C    
  393. X#else /* IBMPC or MAC*/
  394. X    _W|_L,    _W|_L,    _W|_L,    _Op|_P,    _P,    _Cl|_P,    _P,    _C,
  395. X    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  396. X    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  397. X    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  398. X    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  399. X    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  400. X    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  401. X    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  402. X    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
  403. X#endif /* ASCII */
  404. X#ifndef LISP
  405. X}
  406. X#else
  407. X},
  408. X
  409. X{    _C,    _C,    _C,    _C,    _C,    _C,    _C,    _C,
  410. X    _C,    _C,    _C,    _C,    _C,    _C,    _C,    _C,
  411. X    _C,    _C,    _C,    _C,    _C,    _C,    _C,    _C,
  412. X    _C,    _C,    _C,    _C,    _C,    _C,    _C,    _C,
  413. X    _P,    _W|_P,    _P,    _P,    _W|_P,    _W|_P,    _W|_P,    _P,
  414. X    _Op|_P,    _Cl|_P,    _W|_P,    _W|_P,    _P,    _W|_P,    _P,    _W,
  415. X    _W|_N,    _W|_N,    _W|_N,    _W|_N,    _W|_N,    _W|_N,    _W|_N,    _W|_N,
  416. X    _W|_N,    _W|_N,    _W|_P,    _P,    _W|_P,    _W|_P,    _W|_P,    _W|_P,
  417. X    _W|_P,    _W|_U,    _W|_U,    _W|_U,    _W|_U,    _W|_U,    _W|_U,    _W|_U,
  418. X    _W|_U,    _W|_U,    _W|_U,    _W|_U,    _W|_U,    _W|_U,    _W|_U,    _W|_U,
  419. X    _W|_U,    _W|_U,    _W|_U,    _W|_U,    _W|_U,    _W|_U,    _W|_U,    _W|_U,
  420. X    _W|_U,    _W|_U,    _W|_U,    _Op|_P,    _P,    _Cl|_P,    _W|_P,    _W|_P,
  421. X    _P,    _W|_L,    _W|_L,    _W|_L,    _W|_L,    _W|_L,    _W|_L,    _W|_L,
  422. X    _W|_L,    _W|_L,    _W|_L,    _W|_L,    _W|_L,    _W|_L,    _W|_L,    _W|_L,
  423. X    _W|_L,    _W|_L,    _W|_L,    _W|_L,    _W|_L,    _W|_L,    _W|_L,    _W|_L,
  424. X#ifdef ASCII
  425. X    _W|_L,    _W|_L,    _W|_L,    _Op|_W|_P,    _W|_P,    _Cl|_W|_P,    _W|_P,    _W|_C    },
  426. X#else /* IBMPC or MAC */
  427. X    _W|_L,    _W|_L,    _W|_L,    _Op|_W|_P,    _W|_P,    _Cl|_W|_P,    _W|_P,    _W|_C,
  428. X    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  429. X    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  430. X    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  431. X    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  432. X    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  433. X    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  434. X    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  435. X    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0     
  436. X    },
  437. X#endif /* ASCII */
  438. X#endif    /* LISP */
  439. X};
  440. X
  441. int
  442. ismword(c)
  443. X{
  444. X    return ((CharTable[curbuf->b_major])[c]&(_W));
  445. X}
  446. X
  447. X#ifdef IBMPC
  448. char    CaseEquiv[256] = {
  449. X    '\000',    '\001',    '\002',    '\003',    '\004',    '\005',    '\006',    '\007',
  450. X    '\010',    '\011',    '\012',    '\013',    '\014',    '\015',    '\016',    '\017',
  451. X    '\020',    '\021',    '\022',    '\023',    '\024',    '\025',    '\026',    '\027',
  452. X    '\030',    '\031',    '\032',    '\033',    '\034',    '\035',    '\036',    '\037',
  453. X    '\040',    '!',    '"',    '#',    '$',    '%',    '&',    '\'',
  454. X    '(',    ')',    '*',    '+',    ',',    '-',    '.',    '/',
  455. X    '0',    '1',    '2',    '3',    '4',    '5',    '6',    '7',
  456. X    '8',    '9',    ':',    ';',    '<',    '=',    '>',    '?',
  457. X    '@',    'A',    'B',    'C',    'D',    'E',    'F',    'G',
  458. X    'H',    'I',    'J',    'K',    'L',    'M',    'N',    'O',
  459. X    'P',    'Q',    'R',    'S',    'T',    'U',    'V',    'W',
  460. X    'X',    'Y',    'Z',    '[',    '\\',    ']',    '^',    '_',
  461. X    '`',    'A',    'B',    'C',    'D',    'E',    'F',    'G',
  462. X    'H',    'I',    'J',    'K',    'L',    'M',    'N',    'O',
  463. X    'P',    'Q',    'R',    'S',    'T',    'U',    'V',    'W',
  464. X    'X',    'Y',    'Z',    '{',    '|',    '}',    '~',    '\177',
  465. X    128, 154, 130, 131, 142, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 
  466. X    144, 145, 146, 147, 153, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 
  467. X    160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175,
  468. X    176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191,
  469. X    192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 
  470. X    208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223,
  471. X    224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 
  472. X    240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255
  473. X};
  474. X
  475. X#endif /* IBMPC */
  476. X#ifdef MAC
  477. char    CaseEquiv[256] = {
  478. X    '\000',    '\001',    '\002',    '\003',    '\004',    '\005',    '\006',    '\007',
  479. X    '\010',    '\011',    '\012',    '\013',    '\014',    '\015',    '\016',    '\017',
  480. X    '\020',    '\021',    '\022',    '\023',    '\024',    '\025',    '\026',    '\027',
  481. X    '\030',    '\031',    '\032',    '\033',    '\034',    '\035',    '\036',    '\037',
  482. X    '\040',    '!',    '"',    '#',    '$',    '%',    '&',    '\'',
  483. X    '(',    ')',    '*',    '+',    ',',    '-',    '.',    '/',
  484. X    '0',    '1',    '2',    '3',    '4',    '5',    '6',    '7',
  485. X    '8',    '9',    ':',    ';',    '<',    '=',    '>',    '?',
  486. X    '@',    'A',    'B',    'C',    'D',    'E',    'F',    'G',
  487. X    'H',    'I',    'J',    'K',    'L',    'M',    'N',    'O',
  488. X    'P',    'Q',    'R',    'S',    'T',    'U',    'V',    'W',
  489. X    'X',    'Y',    'Z',    '[',    '\\',    ']',    '^',    '_',
  490. X    '`',    'A',    'B',    'C',    'D',    'E',    'F',    'G',
  491. X    'H',    'I',    'J',    'K',    'L',    'M',    'N',    'O',
  492. X    'P',    'Q',    'R',    'S',    'T',    'U',    'V',    'W',
  493. X    'X',    'Y',    'Z',    '{',    '|',    '}',    '~',    '\177',
  494. X    0x80,    0x81,    0x82,    0x83,    0x84,    0x85,    0x86,    0x87,
  495. X    0xCB,    0x89,    0x80,    0xCC,    0x81,    0x82,    0x83,    0x8F,
  496. X    0x90,    0x91,    0x92,    0x93,    0x94,    0x95,    0x84,    0x97,
  497. X    0x98,    0x99,    0x85,    0xCD,    0x9C,    0x9D,    0x9E,    0x86,
  498. X    0xA0,    0xA1,    0xA2,    0xA3,    0xA4,    0xA5,    0xA6,    0xA7,
  499. X    0xA8,    0xA9,    0xAA,    0xAB,    0xAC,    0xAD,    0xAE,    0xAF,
  500. X    0xB0,    0xB1,    0xB2,    0xB3,    0xB4,    0xB5,    0xC6,    0xB7,
  501. X    0xB8,    0xB8,    0xBA,    0xBB,    0xBC,    0xBD,    0xAE,    0xAF,
  502. X    0xC0,    0xC1,    0xC2,    0xC3,    0xC4,    0xC5,    0xC6,    0xC7,
  503. X    0xC8,    0xC9,    0xCA,    0xCB,    0xCC,    0xCD,    0xCE,    0xCE,
  504. X    0xD0,    0xD1,    0xD2,    0xD3,    0xD4,    0xD5,    0xD6,    0xD7,
  505. X    0xD8,    0,        0,        0,        0,        0,        0,        0,
  506. X    0,        0,        0,        0,        0,        0,        0,        0,
  507. X    0,        0,        0,        0,        0,        0,        0,        0,
  508. X    0,        0,        0,        0,        0,        0,        0,        0,
  509. X    0,        0,        0,        0,        0,        0,        0,        0
  510. X};
  511. X#endif /* MAC */
  512. X#ifdef ASCII
  513. char CaseEquiv[] = {
  514. X    '\000',    '\001',    '\002',    '\003',    '\004',    '\005',    '\006',    '\007',
  515. X    '\010',    '\011',    '\012',    '\013',    '\014',    '\015',    '\016',    '\017',
  516. X    '\020',    '\021',    '\022',    '\023',    '\024',    '\025',    '\026',    '\027',
  517. X    '\030',    '\031',    '\032',    '\033',    '\034',    '\035',    '\036',    '\037',
  518. X    '\040',    '!',    '"',    '#',    '$',    '%',    '&',    '\'',
  519. X    '(',    ')',    '*',    '+',    ',',    '-',    '.',    '/',
  520. X    '0',    '1',    '2',    '3',    '4',    '5',    '6',    '7',
  521. X    '8',    '9',    ':',    ';',    '<',    '=',    '>',    '?',
  522. X    '@',    'A',    'B',    'C',    'D',    'E',    'F',    'G',
  523. X    'H',    'I',    'J',    'K',    'L',    'M',    'N',    'O',
  524. X    'P',    'Q',    'R',    'S',    'T',    'U',    'V',    'W',
  525. X    'X',    'Y',    'Z',    '[',    '\\',    ']',    '^',    '_',
  526. X    '`',    'A',    'B',    'C',    'D',    'E',    'F',    'G',
  527. X    'H',    'I',    'J',    'K',    'L',    'M',    'N',    'O',
  528. X    'P',    'Q',    'R',    'S',    'T',    'U',    'V',    'W',
  529. X    'X',    'Y',    'Z',    '{',    '|',    '}',    '~',    '\177'
  530. X};
  531. X
  532. X#endif /* ASCII */
  533. END_OF_FILE
  534. if test 11238 -ne `wc -c <'./ctype.c'`; then
  535.     echo shar: \"'./ctype.c'\" unpacked with wrong size!
  536. fi
  537. # end of './ctype.c'
  538. fi
  539. if test -f './doc/jove.nr' -a "${1}" != "-c" ; then 
  540.   echo shar: Will not clobber existing file \"'./doc/jove.nr'\"
  541. else
  542. echo shar: Extracting \"'./doc/jove.nr'\" \(11791 characters\)
  543. sed "s/^X//" >'./doc/jove.nr' <<'END_OF_FILE'
  544. X.hy 0
  545. X.TH JOVE 1 "12 February 1986"
  546. X.ad
  547. X.SH NAME
  548. jove - an interactive display-oriented text editor
  549. X.SH SYNOPSIS
  550. X.nf
  551. jove [-d directory] [-w] [-t tag] [+[n] file] [-p file] [files]
  552. jove -r
  553. X.fi
  554. X.SH DESCRIPTION
  555. JOVE is Jonathan's Own Version of Emacs.  It is based on the original EMACS
  556. editor written at MIT by Richard Stallman.  Although JOVE is meant to be
  557. compatible with EMACS, there are some major differences between the two
  558. editors and you shouldn't rely on their behaving identically.
  559. X.LP
  560. JOVE works on any reasonable display terminal that is described in the
  561. X.I termcap
  562. file (see TERMCAP(5) for more details).  When you start up JOVE, it checks
  563. to see whether you have your
  564. X.I TERM
  565. environment variable set.  On most systems that will automatically be set up
  566. for you, but if it's not JOVE will ask you what kind of terminal you are
  567. using.  To avoid having to type this every time you run JOVE you can set your
  568. X.I TERM
  569. environment variable yourself.  How you do this depends on which shell you
  570. are running.  If you are running the C Shell, as most of you are, you type
  571. X.sp 1
  572. X     % setenv TERM
  573. X.I type
  574. X.sp 1
  575. and with the Bourne Shell, you type
  576. X.sp 1
  577. X     $ TERM=
  578. X.I type
  579. X; export TERM
  580. X.sp 1
  581. where
  582. X.I type
  583. is the name of the kind of terminal you are using (e.g., vt100).  If
  584. neither of these works get somebody to help you.
  585. X.SH INVOKING JOVE
  586. If you run JOVE with no arguments you will be placed in an empty buffer,
  587. called
  588. X.I Main.
  589. Otherwise, any arguments you supply are considered file names and each is
  590. X"given" its own buffer.  Only the first file is actually read in--reading
  591. other files is deferred until you actually try to use the buffers they are
  592. attached to.  This is for efficiency's sake: most of the time, when you run
  593. JOVE on a big list of files, you end up editing only a few of them.
  594. X.LP
  595. The names of all of the files specified on the command line are saved in a
  596. buffer, called
  597. X.I *minibuf*.
  598. The mini-buffer is a special JOVE buffer that is used when JOVE is prompting
  599. for some input to many commands (for example, when JOVE is prompting for a
  600. file name).  When you are being prompted for a file name, you can type C-N
  601. X(that's Control-N) and C-P to cycle through the list of files that were
  602. specified on the command line.  The file name will be inserted where you are
  603. typing and then you can edit it as if you typed it in yourself.
  604. X.LP
  605. JOVE recognizes the following switches:
  606. X.TP
  607. X.I -d
  608. The following argument is taken to be the name of the current directory.
  609. This is for systems that don't have a version of C shell that automatically
  610. maintains the
  611. X.I CWD
  612. environment variable.  If
  613. X.I -d
  614. is not specified on a system without a modified C shell, JOVE will have to
  615. figure out the current directory itself, and that can be VERY slow.  You
  616. can simulate the modified C shell by putting the following lines in your
  617. C shell initialization file (.cshrc):
  618. X.nf
  619. X.sp 1
  620. X    alias cd        'cd \\!*; setenv CWD $cwd'
  621. X    alias popd      'popd \\!*; setenv CWD $cwd'
  622. X    alias pushd     'pushd \\!*; setenv CWD $cwd'
  623. X.fi
  624. X.TP
  625. X.I +n
  626. Reads the file, designated by the following argument, and positions point at
  627. the
  628. X.I n'th
  629. line instead of the (default) 1'st line.  This can be specified more than
  630. once but it doesn't make sense to use it twice on the same file; in that
  631. case the second one wins. If no numeric argument is given after the +,
  632. the point is positioned at the end of the file.
  633. X.TP
  634. X.I -p
  635. Parses the error messages in the file designated by the following argument.
  636. The error messages are assumed to be in a format similar to the C compiler,
  637. LINT, or GREP output.
  638. X.TP
  639. X.I -t
  640. Runs the
  641. X.I find-tag 
  642. command on the string of characters immediately following 
  643. the -t if there is one (as in -tTagname), or on
  644. the following argument (as in -t Tagname) otherwise (see ctags(1)).
  645. X.TP
  646. X.I -w
  647. Divides the window in two.  When this happens, either the same file is
  648. displayed in both windows, or the second file in the list is read in and
  649. displayed in its window.
  650. X.SH "RECOVERING BUFFERS AFTER A CRASH"
  651. The
  652. X.I -r
  653. option of jove runs the JOVE recover program.  Use this when the system
  654. crashes, or JOVE crashes, or you accidently get logged out while in JOVE.
  655. If there are any buffers to be recovered, this will find them.
  656. X.LP
  657. Recover looks for JOVE buffers that are left around and are
  658. owned by you.  (You cannot recover other peoples' buffers, obviously.)
  659. If there were no buffers that were modified at the time of the
  660. crash or there were but recover can't get its hands on them, you will be
  661. informed with the message, "There is nothing to recover."  Otherwise,
  662. recover prints the date and time of the version of the buffers it has,
  663. and then waits for you type a command.
  664. X.LP
  665. To get a list of the buffers recover knows about, use the
  666. X.I list
  667. command.  This will list all the buffers and the files and the number of
  668. lines associated with them.  Next to each buffer is a number.  When you want
  669. to recover a buffer, use the
  670. X.I get
  671. command.  The syntax is
  672. X.I get buffer filename
  673. where
  674. X.I buffer
  675. is either the buffer's name or the number at the beginning of the line.  If
  676. you don't type the buffer name or the filename, recover will prompt you
  677. for them.
  678. X.LP
  679. If there are a lot of buffers and you want to recover all of them, use the
  680. X.I recover
  681. command.  This will recover each buffer to the name of the buffer with ".#"
  682. prepended to the name (so that the original isn't over-written).  It asks
  683. for each file and if you want to restore that buffer to that name you type
  684. X"yes".  If you want to recover the file but to a different name, just type
  685. the new name in.  If you type "no" recover will skip that file and go on
  686. to the next one.
  687. X.LP
  688. If you want to look at a buffer before deciding to recover it, use the
  689. X.I print
  690. command.  The syntax for this is
  691. X.I print buffer
  692. where
  693. X.I buffer
  694. again is either its name or the number.  You can type ^C if you want to
  695. abort printing the file to the terminal, and recover will respond with
  696. an appropriate message.
  697. X.LP
  698. When you're done and have all the buffers you want, type the
  699. X.I quit
  700. command to leave.  You will then be asked whether it's okay to delete the
  701. tmp files.  Most of the time that's okay and you should type "yes".  When
  702. you say that, JOVE removes all traces of those buffers and you won't be able
  703. to look at them again.  (If you recovered some buffers they will still be
  704. around, so don't worry.)  So, if you're not sure whether you've gotten all
  705. the buffers, you should answer "no" so that you'll be able to run
  706. recover again at a later time (presumably after you've figured out
  707. which ones you want to save).
  708. X.LP
  709. If you type ^C at any time other than when you're printing a file to the
  710. terminal, recover will exit without a word.  If you do this but wish you
  711. hadn't, just type "jove -r" to the shell again, and you will be put back
  712. with no loss.
  713. X.SH GETTING HELP
  714. Once in JOVE, there are several commands available to get help.  To execute
  715. any JOVE command, you type "<ESC> X command-name" followed by <Return>.  To
  716. get a list of all the JOVE commands you type "<ESC> X" followed by "?".  The
  717. X.I describe-bindings
  718. command can be used to get a list containing each key, and its associated
  719. command (that is, the command that gets executed when you type that key).
  720. If you want to save the list of bindings, you can set the jove variable
  721. X.I send-typeout-to-buffer
  722. to ON (using the 
  723. X.I set
  724. command), and then execute the
  725. X.I describe-bindings
  726. command.  This will create a buffer and put in it the bindings list it
  727. normally would have printed on the screen.  Then you can save that buffer to
  728. a file and print it to use as a quick reference card.  (See VARIABLES below.)
  729. X.LP
  730. Once you know the name of a command, you can find out what it does with the
  731. X.I describe-command
  732. command, which you can invoke quickly by typing "ESC ?".  The
  733. X.I apropos
  734. command will give you a list of all the command with a specific string in
  735. their names.  For example, if you want to know the names of all the
  736. commands that are concerned with windows, you can run "apropos" with the
  737. keyword
  738. X.I window.
  739. X.LP
  740. If you're not familar with the EMACS command set, it would be worth your
  741. while to use run TEACHJOVE.  Do do that, just type "teachjove" to your shell
  742. and you will be placed in JOVE in a file which contains directions.  I highly
  743. recommend this for beginners; you may save yourself a lot of time and
  744. headaches.
  745. X.SH KEY BINDINGS and VARIABLES
  746. You can alter the key bindings in JOVE to fit your personal tastes.  That
  747. is, you can change what a key does every time you strike it.  For example,
  748. by default the C-N key is bound to the command
  749. X.I next-line
  750. and so when you type it you move down a line.  If you want to change a
  751. binding or add a new one, you use the
  752. X.I bind-to-key
  753. command.  The syntax is "bind-to-key <command> key".
  754. X.LP
  755. You can also change the way JOVE behaves in little ways by changing the
  756. value of some variables with the
  757. X.I set
  758. command.  The syntax is "set <variable> value", where value is a number or a
  759. string, or "on" or "off", depending on the context.  For example, if you
  760. want JOVE to make backup files, you set the "make-backup-files" variable to
  761. X"on".  To see the value of a variable, use the "print <variable>" command.
  762. X.SH INITIALIZATION
  763. JOVE automatically reads commands from an initialization file in your HOME
  764. directory, called ".joverc".  In this file you can place commands that you
  765. would normally type in JOVE.  If you like to rearrange the key bindings and
  766. set some variables every time you get into JOVE, you should put them in your
  767. initialization file.  Here are a few lines from mine:
  768. X.nf
  769. X    set match-regular-expressions on
  770. X    auto-execute-command auto-fill /tmp/Re\\|.*drft
  771. X    bind-to-key i-search-forward ^\\
  772. X    bind-to-key i-search-reverse ^R
  773. X    bind-to-key find-tag-at-point ^[^T
  774. X    bind-to-key scroll-down ^C
  775. X    bind-to-key grow-window ^Xg
  776. X    bind-to-key shrink-window ^Xs
  777. X.fi
  778. X(Note that the Control Characters can be either two character sequences
  779. X(e.g. ^ and C together as ^C) or the actual control character.  If you want
  780. to use an ^ by itself you must BackSlash it (e.g., bind-to-key grow-window
  781. X^X\\^ binds grow-window to "^X^").
  782. X.SH SOME MINOR DETAILS
  783. You should type C-\\ instead of C-S in many instances.  For example, the way
  784. to search for a string is documented as being "C-S" but in reality you
  785. should type "C-\\".  This is because C-S is the XOFF character (what gets
  786. sent when you type the NO SCROLL key), and clearly that won't work.  The XON
  787. character is "C-Q" (what gets sent when you type NO SCROLL again) which is
  788. documented as the way to do a quoted-insert.  The alternate key for this is
  789. X"C-^" (typed as "C-`" on vt100's and its look-alikes).  If you want to
  790. enable C-S and C-Q and you know what you are doing, you can put the line:
  791. X.nf
  792. X    set allow-^S-and-^Q on
  793. X.fi
  794. in your initialization file.
  795. X.LP
  796. If your terminal has a metakey, JOVE will use it if you turn on the
  797. X"meta-key" variable.  JOVE will automatically turn on "meta-key" if the
  798. METAKEY environment variable exists.  This is useful for if you have
  799. different terminals (e.g., one at home and one at work) and one has a
  800. metakey and the other doesn't.
  801. X.SH FILES
  802. LIBDIR/.joverc - system wide initialization file
  803. X.sp 0
  804. X~/.joverc - personal initialization file
  805. X.sp 0
  806. TMPDIR - where temporary files are stored
  807. X.sp 0
  808. LIBDIR/teach-jove - the interactive tutorial
  809. X.sp 0
  810. LIBDIR/portsrv - for running shells in windows (pdp11 only)
  811. X.SH SEE ALSO
  812. X.nf
  813. ed(1) - for a description of regular expressions
  814. X.sp 0
  815. teachjove(1) - for an interactive JOVE tutorial.
  816. X.fi
  817. X.SH DIAGNOSTICS
  818. JOVE diagnostics are meant to be self-explanatory, but you are advised
  819. to seek help whenever you are confused.  You can easily lose a lot of
  820. work if you don't know EXACTLY what you are doing.
  821. X.SH BUGS
  822. Lines can't be more than 1024 characters long.
  823. X.sp 1
  824. Searches can't cross line boundaries.
  825. X.SH AUTHOR
  826. Jonathan Payne
  827. END_OF_FILE
  828. if test 11791 -ne `wc -c <'./doc/jove.nr'`; then
  829.     echo shar: \"'./doc/jove.nr'\" unpacked with wrong size!
  830. fi
  831. # end of './doc/jove.nr'
  832. fi
  833. if test -f './re1.c' -a "${1}" != "-c" ; then 
  834.   echo shar: Will not clobber existing file \"'./re1.c'\"
  835. else
  836. echo shar: Extracting \"'./re1.c'\" \(11936 characters\)
  837. sed "s/^X//" >'./re1.c' <<'END_OF_FILE'
  838. X/***************************************************************************
  839. X * This program is Copyright (C) 1986, 1987, 1988 by Jonathan Payne.  JOVE *
  840. X * is provided to you without charge, and with no warranty.  You may give  *
  841. X * away copies of JOVE, including sources, provided that this notice is    *
  842. X * included in all the files.                                              *
  843. X ***************************************************************************/
  844. X
  845. X#include "jove.h"
  846. X#include "io.h"
  847. X#include "re.h"
  848. X#include "ctype.h"
  849. X
  850. X#ifdef MAC
  851. X#    include "mac.h"
  852. X#else
  853. X#    include <sys/stat.h>
  854. X#endif
  855. X
  856. X#ifdef MAC
  857. X#    undef private
  858. X#    define private
  859. X#endif
  860. X
  861. X#ifdef    LINT_ARGS
  862. private Bufpos * doisearch(int, int, int);
  863. X
  864. private void
  865. X    IncSearch(int),
  866. X    replace(int, int);
  867. private int
  868. X    isearch(int, Bufpos *),
  869. X    lookup(char *, char *, char *, char *),
  870. X    substitute(int, Line *, int, Line *, int);
  871. X#else
  872. private Bufpos * doisearch();
  873. X
  874. private void
  875. X    IncSearch(),
  876. X    replace();
  877. private int
  878. X    isearch(),
  879. X    lookup(),
  880. X    substitute();
  881. X#endif    /* LINT_ARGS */
  882. X
  883. X#ifdef MAC
  884. X#    undef private
  885. X#    define private static
  886. X#endif
  887. X
  888. private int
  889. substitute(query, l1, char1, l2, char2)
  890. Line    *l1,
  891. X    *l2;
  892. X{
  893. X    Line    *lp;
  894. X    int    numdone = 0,
  895. X        offset = curchar,
  896. X        stop = NO;
  897. X    disk_line    UNDO_da = 0;
  898. X    Line        *UNDO_lp = 0;
  899. X
  900. X    lsave();
  901. X    REdirection = FORWARD;
  902. X
  903. X    lp = l1;
  904. X    for (lp = l1; (lp != l2->l_next) && !stop; lp = lp->l_next) {
  905. X        offset = (lp == l1) ? char1 : 0;
  906. X        while (!stop && re_lindex(lp, offset, compbuf, alternates, 0)) {
  907. X            if (lp == l2 && REeom > char2)    /* nope, leave this alone */
  908. X                break;
  909. X            DotTo(lp, REeom);
  910. X            offset = curchar;
  911. X            if (query) {
  912. X                message("Replace (Type '?' for help)? ");
  913. reswitch:            redisplay();
  914. X                switch (CharUpcase(getchar())) {
  915. X                case '.':
  916. X                    stop = YES;
  917. X                    /* Fall into ... */
  918. X
  919. X                case ' ':
  920. X                case 'Y':
  921. X                    break;
  922. X
  923. X                case BS:
  924. X                case RUBOUT:
  925. X                case 'N':
  926. X                    if (linebuf[offset++] == '\0')
  927. X                        goto nxtline;
  928. X                    continue;
  929. X
  930. X                case CTL('W'):
  931. X                    re_dosub(linebuf, YES);
  932. X                    numdone += 1;
  933. X                    offset = curchar = REbom;
  934. X                    makedirty(curline);
  935. X                    /* Fall into ... */
  936. X
  937. X                case CTL('R'):
  938. X                case 'R':
  939. X                    RErecur();
  940. X                    offset = curchar;
  941. X                    lp = curline;
  942. X                    continue;
  943. X
  944. X                case CTL('U'):
  945. X                case 'U':
  946. X                    if (UNDO_lp == 0)
  947. X                        continue;
  948. X                    lp = UNDO_lp;
  949. X                    lp->l_dline = UNDO_da | DIRTY;
  950. X                    offset = 0;
  951. X                    numdone -= 1;
  952. X                    continue;
  953. X
  954. X                case 'P':
  955. X                case '!':
  956. X                    query = 0;
  957. X                    break;
  958. X
  959. X                case CR:
  960. X                case LF:
  961. X                case 'Q':
  962. X                    goto done;
  963. X
  964. X                case CTL('L'):
  965. X                    RedrawDisplay();
  966. X                    goto reswitch;
  967. X
  968. X                default:
  969. X                    rbell();
  970. message("Space or Y, Period, Rubout or N, C-R or R, C-W, C-U or U, P or !, Return.");
  971. X                    goto reswitch;
  972. X                }
  973. X            }
  974. X            re_dosub(linebuf, NO);
  975. X            numdone += 1;
  976. X            modify();
  977. X            offset = curchar = REeom;
  978. X            makedirty(curline);
  979. X            if (query) {
  980. X                message(mesgbuf);    /* no blinking */
  981. X                redisplay();        /* show the change */
  982. X            }
  983. X            UNDO_da = curline->l_dline;
  984. X            UNDO_lp = curline;
  985. X            if (linebuf[offset] == 0)
  986. nxtline:            break;
  987. X        }
  988. X    }
  989. done:    return numdone;
  990. X}
  991. X
  992. X/* prompt for search and replacement strings and do the substitution */
  993. private void
  994. replace(query, inreg)
  995. X{
  996. X    Mark    *m;
  997. X    char    *rep_ptr;
  998. X    Line    *l1 = curline,
  999. X        *l2 = curbuf->b_last;
  1000. X    int    char1 = curchar,
  1001. X        char2 = length(curbuf->b_last),
  1002. X        numdone;
  1003. X
  1004. X    if (inreg) {
  1005. X        m = CurMark();
  1006. X        l2 = m->m_line;
  1007. X        char2 = m->m_char;
  1008. X        (void) fixorder(&l1, &char1, &l2, &char2);
  1009. X    }
  1010. X
  1011. X    /* get search string */
  1012. X    strcpy(rep_search, ask(rep_search[0] ? rep_search : (char *) 0, ProcFmt));
  1013. X    REcompile(rep_search, UseRE, compbuf, alternates);
  1014. X    /* Now the replacement string.  Do_ask() so the user can play with
  1015. X       the default (previous) replacement string by typing C-R in ask(),
  1016. X       OR, he can just hit Return to replace with nothing. */
  1017. X    rep_ptr = do_ask("\r\n", (int (*)()) 0, rep_str, ": %f %s with ", rep_search);
  1018. X    if (rep_ptr == 0)
  1019. X        rep_ptr = NullStr;
  1020. X    strcpy(rep_str, rep_ptr);
  1021. X
  1022. X    if (((numdone = substitute(query, l1, char1, l2, char2)) != 0) &&
  1023. X        (inreg == NO)) {
  1024. X        do_set_mark(l1, char1);
  1025. X        add_mess(" ");        /* just making things pretty */
  1026. X    } else
  1027. X        message("");
  1028. X    add_mess("(%d substitution%n)", numdone, numdone);
  1029. X}
  1030. X
  1031. void
  1032. RegReplace()
  1033. X{
  1034. X    replace(0, YES);
  1035. X}
  1036. X
  1037. void
  1038. QRepSearch()
  1039. X{
  1040. X    replace(1, NO);
  1041. X}
  1042. X
  1043. void
  1044. RepSearch()
  1045. X{
  1046. X    replace(0, NO);
  1047. X}
  1048. X
  1049. X/* Lookup a tag in tag file FILE.  FILE is assumed to be sorted
  1050. X   alphabetically.  The FASTTAGS code, which is implemented with
  1051. X   a binary search, depends on this assumption.  If it's not true
  1052. X   it is possible to comment out the fast tag code (which is clearly
  1053. X   labeled) and everything else will just work. */
  1054. X
  1055. private int
  1056. lookup(searchbuf, filebuf, tag, file)
  1057. char    *searchbuf,
  1058. X    *filebuf,
  1059. X    *tag,
  1060. X    *file;
  1061. X{
  1062. X    register int    taglen = strlen(tag);
  1063. X    char    line[BUFSIZ],
  1064. X        pattern[128];
  1065. X    register File    *fp;
  1066. X    struct stat    stbuf;
  1067. X    int    fast = YES,
  1068. X        success = NO;
  1069. X    register off_t    lower, upper;
  1070. X
  1071. X    sprintf(pattern, "^%s[^\t]*\t*\\([^\t]*\\)\t*[?/]\\([^?/]*\\)[?/]", tag);
  1072. X    fp = open_file(file, iobuff, F_READ, !COMPLAIN, QUIET);
  1073. X    if (fp == NIL)
  1074. X        return 0;
  1075. X
  1076. X    /* ********BEGIN FAST TAG CODE******** */
  1077. X
  1078. X    if (stat(file, &stbuf) < 0)
  1079. X        fast = NO;
  1080. X    else {
  1081. X        lower = 0;
  1082. X        upper = stbuf.st_size;
  1083. X        if (upper - lower < BUFSIZ)
  1084. X            fast = NO;
  1085. X    }
  1086. X    if (fast == YES) for (;;) {
  1087. X        off_t    mid;
  1088. X        int    whichway,
  1089. X            chars_eq;
  1090. X
  1091. X        if (upper - lower < BUFSIZ) {
  1092. X            f_seek(fp, lower);
  1093. X            break;            /* stop this nonsense */
  1094. X        }
  1095. X        mid = (lower + upper) / 2;
  1096. X        f_seek(fp, mid);
  1097. X        f_toNL(fp);
  1098. X        if (f_gets(fp, line, sizeof line) == EOF)
  1099. X            break;
  1100. X        chars_eq = numcomp(line, tag);
  1101. X        if (chars_eq == taglen && iswhite(line[chars_eq]))
  1102. X            goto found;
  1103. X        whichway = line[chars_eq] - tag[chars_eq];
  1104. X        if (whichway < 0) {        /* line is BEFORE tag */
  1105. X            lower = mid;
  1106. X            continue;
  1107. X        } else if (whichway > 0) {    /* line is AFTER tag */
  1108. X            upper = mid;
  1109. X            continue;
  1110. X        }
  1111. X    }
  1112. X    f_toNL(fp);
  1113. X    /* END FAST TAG CODE */
  1114. X
  1115. X    while (f_gets(fp, line, sizeof line) != EOF) {
  1116. X        int    cmp;
  1117. X
  1118. X        if (line[0] > *tag)
  1119. X            break;
  1120. X        else if ((cmp = strncmp(line, tag, taglen)) > 0)
  1121. X            break;
  1122. X        else if (cmp < 0)
  1123. X            continue;
  1124. X        /* if we get here, we've found the match */
  1125. found:        if (!LookingAt(pattern, line, 0)) {
  1126. X            complain("I thought I saw it!");
  1127. X            break;
  1128. X        } else {
  1129. X            putmatch(1, filebuf, FILESIZE);
  1130. X            putmatch(2, searchbuf, 100);
  1131. X            success = YES;
  1132. X            break;
  1133. X        }
  1134. X    }
  1135. X    close_file(fp);
  1136. X        
  1137. X    if (success == NO)
  1138. X        s_mess("Can't find tag \"%s\".", tag);
  1139. X    return success;
  1140. X}
  1141. X
  1142. X#ifndef MSDOS
  1143. char    TagFile[FILESIZE] = "./tags";
  1144. X#else /* MSDOS */
  1145. char    TagFile[FILESIZE] = "tags";
  1146. X#endif /* MSDOS */
  1147. X
  1148. void
  1149. find_tag(tag, localp)
  1150. char    *tag;
  1151. X{
  1152. X    char    filebuf[FILESIZE],
  1153. X        sstr[100],
  1154. X        tfbuf[FILESIZE];
  1155. X    register Bufpos    *bp;
  1156. X    register Buffer    *b;
  1157. X    char    *tagfname;
  1158. X
  1159. X    if (!localp) {
  1160. X        char    prompt[128];
  1161. X
  1162. X        sprintf(prompt, "With tag file (%s default): ", TagFile);
  1163. X        tagfname = ask_file(prompt, TagFile, tfbuf);
  1164. X    } else
  1165. X        tagfname = TagFile;
  1166. X    if (lookup(sstr, filebuf, tag, tagfname) == 0)
  1167. X        return;
  1168. X    set_mark();
  1169. X    b = do_find(curwind, filebuf, 0);
  1170. X    if (curbuf != b)
  1171. X        SetABuf(curbuf);
  1172. X    SetBuf(b);
  1173. X    if ((bp = dosearch(sstr, BACKWARD, 0)) == 0 &&
  1174. X        ((bp = dosearch(sstr, FORWARD, 0)) == 0))
  1175. X        message("Well, I found the file, but the tag is missing.");
  1176. X    else
  1177. X        SetDot(bp);
  1178. X}
  1179. X
  1180. void
  1181. FindTag()
  1182. X{
  1183. X    int    localp = !is_an_arg();
  1184. X    char    tag[128];
  1185. X
  1186. X    strcpy(tag, ask((char *) 0, ProcFmt));
  1187. X    find_tag(tag, localp);
  1188. X}
  1189. X
  1190. X/* Find Tag at Dot. */
  1191. X
  1192. void
  1193. FDotTag()
  1194. X{
  1195. X    int    c1 = curchar,
  1196. X        c2 = c1;
  1197. X    char    tagname[50];
  1198. X
  1199. X    if (!ismword(linebuf[curchar]))
  1200. X        complain("Not a tag!");
  1201. X    while (c1 > 0 && ismword(linebuf[c1 - 1]))
  1202. X        c1 -= 1;
  1203. X    while (ismword(linebuf[c2]))
  1204. X        c2 += 1;
  1205. X
  1206. X    null_ncpy(tagname, linebuf + c1, c2 - c1);
  1207. X    find_tag(tagname, !is_an_arg());
  1208. X}
  1209. X
  1210. X/* I-search returns a code saying what to do:
  1211. X   STOP:    We found the match, so unwind the stack and leave
  1212. X        where it is.
  1213. X   DELETE:    Rubout the last command.
  1214. X   BACKUP:    Back up to where the isearch was last NOT failing.
  1215. X
  1216. X   When a character is typed it is appended to the search string, and
  1217. X   then, isearch is called recursively.  When C-S or C-R is typed, isearch
  1218. X   is again called recursively. */
  1219. X
  1220. X#define STOP    1
  1221. X#define DELETE    2
  1222. X#define BACKUP    3
  1223. X#define TOSTART    4
  1224. X
  1225. static char    ISbuf[128],
  1226. X        *incp = 0;
  1227. int    SExitChar = CR;
  1228. X
  1229. X#define cmp_char(a, b)    ((a) == (b) || (CaseIgnore && (CharUpcase(a) == CharUpcase(b))))
  1230. X
  1231. static Bufpos *
  1232. doisearch(dir, c, failing)
  1233. register int    c,
  1234. X        dir,
  1235. X        failing;
  1236. X{
  1237. X    static Bufpos    buf;
  1238. X    Bufpos    *bp;
  1239. X    extern int    okay_wrap;
  1240. X
  1241. X    if (c == CTL('S') || c == CTL('R'))
  1242. X        goto dosrch;
  1243. X
  1244. X    if (failing)
  1245. X        return 0;
  1246. X    DOTsave(&buf);
  1247. X    if (dir == FORWARD) {
  1248. X        if (cmp_char(linebuf[curchar], c)) {
  1249. X            buf.p_char = curchar + 1;
  1250. X            return &buf;
  1251. X        }
  1252. X    } else {
  1253. X        if (look_at(ISbuf))
  1254. X            return &buf;
  1255. X    }
  1256. dosrch:    okay_wrap = YES;
  1257. X    if ((bp = dosearch(ISbuf, dir, 0)) == 0)
  1258. X        rbell();    /* ring the first time there's no match */
  1259. X    okay_wrap = NO;
  1260. X    return bp;
  1261. X}
  1262. X
  1263. void
  1264. IncFSearch()
  1265. X{
  1266. X    IncSearch(FORWARD);
  1267. X}
  1268. X
  1269. void
  1270. IncRSearch()
  1271. X{
  1272. X    IncSearch(BACKWARD);
  1273. X}
  1274. X
  1275. private void
  1276. IncSearch(dir)
  1277. X{
  1278. X    Bufpos    save_env;
  1279. X
  1280. X    DOTsave(&save_env);
  1281. X    ISbuf[0] = 0;
  1282. X    incp = ISbuf;
  1283. X    if (isearch(dir, &save_env) == TOSTART)
  1284. X        SetDot(&save_env);
  1285. X    else {
  1286. X        if (LineDist(curline, save_env.p_line) >= MarkThresh)
  1287. X            do_set_mark(save_env.p_line, save_env.p_char);
  1288. X    }
  1289. X    setsearch(ISbuf);
  1290. X}
  1291. X
  1292. X/* Nicely recursive. */
  1293. X
  1294. private int
  1295. isearch(dir, bp)
  1296. Bufpos    *bp;
  1297. X{
  1298. X    Bufpos    pushbp;
  1299. X    int    c,
  1300. X        ndir,
  1301. X        failing;
  1302. X    char    *orig_incp;
  1303. X
  1304. X    if (bp != 0) {        /* Move to the new position. */
  1305. X        pushbp.p_line = bp->p_line;
  1306. X        pushbp.p_char = bp->p_char;
  1307. X        SetDot(bp);
  1308. X        failing = 0;
  1309. X    } else {
  1310. X        DOTsave(&pushbp);
  1311. X        failing = 1;
  1312. X    }
  1313. X    orig_incp = incp;
  1314. X    ndir = dir;        /* Same direction as when we got here, unless
  1315. X                   we change it with C-S or C-R. */
  1316. X    for (;;) {
  1317. X        SetDot(&pushbp);
  1318. X        message(NullStr);
  1319. X        if (failing)
  1320. X            add_mess("Failing ");
  1321. X        if (dir == BACKWARD)
  1322. X            add_mess("reverse-");
  1323. X        add_mess("I-search: %s", ISbuf);
  1324. X        DrawMesg(NO);
  1325. X        add_mess(NullStr);    /* tell me this is disgusting ... */
  1326. X        c = getch();
  1327. X        if (c == SExitChar)
  1328. X            return STOP;
  1329. X        if (c == AbortChar) {
  1330. X            /* If we're failing, we backup until we're no longer
  1331. X               failing or we've reached the beginning; else, we
  1332. X               just about the search and go back to the start. */
  1333. X            if (failing)
  1334. X                return BACKUP;
  1335. X            return TOSTART;
  1336. X        }
  1337. X        switch (c) {
  1338. X        case RUBOUT:
  1339. X        case BS:
  1340. X            return DELETE;
  1341. X
  1342. X        case CTL('\\'):
  1343. X            c = CTL('S');
  1344. X
  1345. X        case CTL('S'):
  1346. X        case CTL('R'):
  1347. X            /* If this is the first time through and we have a
  1348. X               search string left over from last time, use that
  1349. X               one now. */
  1350. X            if (incp == ISbuf) {
  1351. X                strcpy(ISbuf, getsearch());
  1352. X                incp = &ISbuf[strlen(ISbuf)];
  1353. X            }
  1354. X            ndir = (c == CTL('S')) ? FORWARD : BACKWARD;
  1355. X            /* If we're failing and we're not changing our
  1356. X               direction, don't recur since there's no way
  1357. X               the search can work. */
  1358. X            if (failing && ndir == dir) {
  1359. X                rbell();
  1360. X                continue;
  1361. X            }
  1362. X            break;
  1363. X
  1364. X        case '\\':
  1365. X            if (incp > &ISbuf[(sizeof ISbuf) - 1]) {
  1366. X                rbell();
  1367. X                continue;
  1368. X            }
  1369. X            *incp++ = '\\';
  1370. X            add_mess("\\");
  1371. X            /* Fall into ... */
  1372. X
  1373. X        case CTL('Q'):
  1374. X        case CTL('^'):
  1375. X            add_mess("");
  1376. X            c = getch() | 0400;
  1377. X            /* Fall into ... */
  1378. X
  1379. X        default:
  1380. X            if (c & 0400)
  1381. X                c &= CHARMASK;
  1382. X            else {
  1383. X#ifdef IBMPC
  1384. X                if (c == RUBOUT || c == 0xff || (c < ' ' && c != '\t')) {
  1385. X#else
  1386. X                if (c > RUBOUT || (c < ' ' && c != '\t')) {
  1387. X#endif
  1388. X                    Ungetc(c);
  1389. X                    return STOP;
  1390. X                }
  1391. X            }
  1392. X            if (incp > &ISbuf[(sizeof ISbuf) - 1]) {
  1393. X                rbell();
  1394. X                continue;
  1395. X            }
  1396. X            *incp++ = c;
  1397. X            *incp = 0;
  1398. X            break;
  1399. X        }
  1400. X        add_mess("%s", orig_incp);
  1401. X        add_mess(" ...");    /* so we know what's going on */
  1402. X        DrawMesg(NO);        /* do it now */
  1403. X        switch (isearch(ndir, doisearch(ndir, c, failing))) {
  1404. X        case TOSTART:
  1405. X            return TOSTART;
  1406. X
  1407. X        case STOP:
  1408. X            return STOP;
  1409. X
  1410. X        case BACKUP:
  1411. X            /* If we're not failing, we just continue to to the
  1412. X               for loop; otherwise we keep returning to the 
  1413. X               previous levels until we find one that isn't
  1414. X               failing OR we reach the beginning. */
  1415. X            if (failing)
  1416. X                return BACKUP;
  1417. X            /* Fall into ... */
  1418. X
  1419. X        case DELETE:
  1420. X            incp = orig_incp;
  1421. X            *incp = 0;
  1422. X            continue;
  1423. X        }
  1424. X    }
  1425. X}
  1426. END_OF_FILE
  1427. if test 11936 -ne `wc -c <'./re1.c'`; then
  1428.     echo shar: \"'./re1.c'\" unpacked with wrong size!
  1429. fi
  1430. # end of './re1.c'
  1431. fi
  1432. echo shar: End of archive 5 \(of 21\).
  1433. cp /dev/null ark5isdone
  1434. MISSING=""
  1435. for I in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 ; do
  1436.     if test ! -f ark${I}isdone ; then
  1437.     MISSING="${MISSING} ${I}"
  1438.     fi
  1439. done
  1440. if test "${MISSING}" = "" ; then
  1441.     echo You have unpacked all 21 archives.
  1442.     rm -f ark[1-9]isdone ark[1-9][0-9]isdone
  1443. else
  1444.     echo You still need to unpack the following archives:
  1445.     echo "        " ${MISSING}
  1446. fi
  1447. ##  End of shell archive.
  1448. exit 0
  1449.